#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <UIKit/UIKit.h>
#import <UIKit/UIApplication.h>
#import <Preferences/PSSpecifier.h>
#import <LockInfo/Plugin.h>

#import "framework/FWCommon.h"
#import "framework/FWApplication.h"

#import "PICommon.h"
#import "PIIntegration.h"
#import "PIContextObject.h"
#import "PIPlugin.h"

#import "PITagPrefs.h"


static NSString* const kTagKey = @"tagKey";
static NSString* const kNoTagKey = @"-1";


@implementation PITagPrefs

@synthesize hidden;


// ******************************************************************************************
#pragma mark -
#pragma mark Initialisation and object management

- (id)initForContentSize:(CGSize)contentSize
{
	DebugLog(@"LI:PICommon: initForContentSize ##########################################");
    
    [_specifiers release];
    _specifiers = nil;
    [hidden release];
    
    if ([super respondsToSelector:@selector(initForContentSize:)])
        self = [super initForContentSize:contentSize];
    else
        self = [super init];
    
    return self;
}

- (void)dealloc
{
	DebugLog(@"LI:PICommon: dealloc ##########################################");
    
    [_specifiers release];
    _specifiers = nil;
    [hidden release];
    
    [super dealloc];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Get switch state

- (CFBooleanRef)stateForSpecifier:(PSSpecifier*)spec
{
    NSString* item = [spec propertyForKey:kTagKey];
    NSString* key = [self.specifier.properties valueForKey:@"defaults"];
    [spec.properties setValue:key forKey:@"defaults"];

    if ([item isEqualToString:kNoTagKey]) {
        Boolean exists;
        BOOL noTags = CFPreferencesGetAppBooleanValue((CFStringRef)kPIOptionsNoTagsFilter, (CFStringRef)key, &exists);
        if (!exists)
            noTags = kPIOptionsNoTagsFilterDefault;
        DebugLog(@"LI:PICommon: NoTags value for %@, item=%@, key=%@, value=%d", spec.name, item, key, noTags);
        return noTags ? kCFBooleanTrue : kCFBooleanFalse;
    }

    if (!self.hidden) {
        NSArray* items = (NSArray*)CFPreferencesCopyAppValue((CFStringRef)kPIOptionsTagsFilters, (CFStringRef)key);
        self.hidden = items ? [NSMutableArray arrayWithArray:items] : [NSMutableArray arrayWithCapacity:10];
        [items release];
    }
    
    DebugLog(@"LI:PICommon: Getting value for %@, item=%@, key=%@, hidden=%@", spec.name, item, key, self.hidden);
    
    return [self.hidden indexOfObject:item] == NSNotFound ? kCFBooleanFalse : kCFBooleanTrue;
}


// ******************************************************************************************
#pragma mark -
#pragma mark Get list of Tags

- (void)setState:(CFBooleanRef)show forSpecifier:(PSSpecifier*)spec
{
    DebugLog(@"LI:PICommon: set %@ value %@", spec, show);
    
    NSString* key = [spec propertyForKey:@"defaults"];
    NSString* item = [spec propertyForKey:kTagKey];
    
    if ([item isEqualToString:kNoTagKey]) {
        CFPreferencesSetAppValue((CFStringRef)kPIOptionsNoTagsFilter, show, (CFStringRef)key);
        CFPreferencesAppSynchronize((CFStringRef)key);
        DebugLog(@"LI:PICommon: Set NoTags value for %@, item=%@, key=%@, value=%d", spec.name, item, key, CFBooleanGetValue(show) ? 1 : 0);
        return;
    }

    if (!self.hidden)
        self.hidden = [NSMutableArray arrayWithCapacity:10];
    
    if (CFBooleanGetValue(show)) {
        if ([hidden indexOfObject:item] == NSNotFound)
            [hidden addObject:item];
    }
    else {
        NSInteger idx = [hidden indexOfObject:item];
        if (idx != NSNotFound)
            [hidden removeObjectAtIndex:idx];
    }
    
    DebugLog(@"LI:PICommon: Key %@", key);
    DebugLog(@"LI:PICommon: Hidden pocket informant Tags %@", hidden);
    
    CFPreferencesSetAppValue((CFStringRef)kPIOptionsTagsFilters, hidden, (CFStringRef)key);
    CFPreferencesAppSynchronize((CFStringRef)key);
}


// ******************************************************************************************
#pragma mark -
#pragma mark Get list of tags

- (NSArray *)specifiers
{
    if (_specifiers == nil) {
        NSArray* tags = [NSArray array];
        
        UIPasteboard* pasteBoard = [UIPasteboard pasteboardWithName:kPIStatusPasteboard create:NO];
        NSArray* dbPaths = [pasteBoard valuesForPasteboardType:kPIPasteboardDBPath inItemSet:nil];
        NSString* dbPath = dbPaths.count == 1 ? FWStringValueFromData([dbPaths objectAtIndex:0]) : nil;
        NSArray* piVersions = [pasteBoard valuesForPasteboardType:kPIPasteboardPIVersion inItemSet:nil];
        NSString* piVersion = piVersions.count == 1 ? FWStringValueFromData([piVersions objectAtIndex:0]) : nil;

        if (dbPath && piVersion) {
            FWApplication* app = [[FWApplication alloc] init];
            app.databasePath = dbPath;
            app.fwPlugin = [[[PIPlugin alloc] initWithPocketInformant2:[piVersion isEqualToString:@"2"]] autorelease];
            
            tags = [PIIntegration arrayOfTags:app keys:nil];
            [app release];
        }
        
        NSMutableArray* specifiers = [NSMutableArray arrayWithCapacity:tags.count];

        NSBundle* bundle = [NSBundle bundleForClass:[self class]];
        PSSpecifier* ps = [PSSpecifier preferenceSpecifierNamed:[PIIntegration stringForTitle:localize(bundle, @"Filters/No Tags")
                                                                                     withIcon:nil
                                                                              withProjectIcon:nil]                                                                     
                                                         target:self
                                                            set:@selector(setState:forSpecifier:)
                                                            get:@selector(stateForSpecifier:)
                                                         detail:Nil
                                                           cell:PSSwitchCell
                                                           edit:Nil];
        [ps setProperty:kNoTagKey forKey:kTagKey];
        
        [specifiers addObject:ps];

        [specifiers addObject:[PSSpecifier groupSpecifierWithName:nil]];

        for (PIContextObject* tag in tags) {
            
            PSSpecifier* ps = [PSSpecifier preferenceSpecifierNamed:[PIIntegration stringForTitle:tag.name
                                                                                         withIcon:tag.icon
                                                                                  withProjectIcon:nil]                                                                     
                                                             target:self
                                                                set:@selector(setState:forSpecifier:)
                                                                get:@selector(stateForSpecifier:)
                                                             detail:Nil
                                                               cell:PSSwitchCell
                                                               edit:Nil];
            [ps setProperty:[[NSNumber numberWithInt:tag.key] stringValue] forKey:kTagKey];
            
            [specifiers addObject:ps];
        }
        
        _specifiers = [specifiers retain];
        
        self.hidden = nil;
    }
    
    return _specifiers;
}

@end
